package com.csesteel.common.dao.impl;

import com.csesteel.common.dao.BaseDao;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * hibernate4实现接口
 */
public class BaseDaoHibernate4<T> implements BaseDao<T>
{
    // DAO组件进行持久化操作底层依赖的SessionFactory组件
    @Autowired
    private SessionFactory sessionFactory;
    // 依赖注入SessionFactory所需的setter方法
//    public void setSessionFactory(SessionFactory sessionFactory)
//    {
//        this.sessionFactory = sessionFactory;
//    }
//    public SessionFactory sessionFactory
//    {
//        return this.sessionFactory;
//    }
    // 根据ID加载实体
    @SuppressWarnings("unchecked")
    public T get(Class<T> entityClazz , Serializable id)
    {
        return (T)sessionFactory.getCurrentSession()
                .get(entityClazz , id);
    }
    // 保存实体
    public Serializable save(T entity)
    {
        return sessionFactory.getCurrentSession()
                .save(entity);
    }
    // 更新实体
    public void update(T entity)
    {
        sessionFactory.getCurrentSession().saveOrUpdate(entity);
    }
    // 删除实体
    public void delete(T entity)
    {
        sessionFactory.getCurrentSession().delete(entity);
    }
    // 根据ID删除实体
    public void delete(Class<T> entityClazz , Serializable id)
    {
        sessionFactory.getCurrentSession()
                .createQuery("delete " + entityClazz.getSimpleName()
                        + " en where en.id = ?0")
                .setParameter("0" , id)
                .executeUpdate();
    }
    // 获取所有实体
    public List<T> findAll(Class<T> entityClazz)
    {
        return find("select en from "
                + entityClazz.getSimpleName() + " en");
    }
    // 获取实体总数

    public long findCount(Class<T> entityClazz)
    {
        List<?> l = find("select count(*) from "
                + entityClazz.getSimpleName());
        // 返回查询得到的实体总数
        if (l != null && l.size() == 1 )
        {
            return (Long)l.get(0);
        }
        return 0;
    }

    /**
     * 根据sql语句删除
     */
    public void deleteBySQL(String sql) {
        sessionFactory.getCurrentSession().createSQLQuery(sql).executeUpdate();
    }
    /**
     * 原生sql执行
     * @param sql
     * @param objs
     * @return
     * @throws Exception
     */
    public List<Object[]> findWithSql(String sql, Object[] params) throws Exception {
        Query q =  sessionFactory.getCurrentSession().createSQLQuery(sql);
        int i = 0;
        if(params != null){
            for (Object o : params) {
                q.setParameter(i, o);
                i++;
            }
        }
        return q.list();
    }
    /**
     * 根据sql语句查询map
     */
    public Map selectBySQLMap(String sql) {
        return (HashMap)sessionFactory.getCurrentSession().createSQLQuery(sql).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
    }
    // 根据HQL语句查询实体
    @SuppressWarnings("unchecked")
    protected List<T> find(String hql)
    {
        return (List<T>)sessionFactory.getCurrentSession()
                .createQuery(hql)
                .list();
    }
    // 根据带占位符参数HQL语句查询实体
    @SuppressWarnings("unchecked")
    protected List<T> find(String hql , Object... params)
    {
        // 创建查询
        Query query = sessionFactory.getCurrentSession()
                .createQuery(hql);
        // 为包含占位符的HQL语句设置参数
        for(int i = 0 , len = params.length ; i < len ; i++)
        {
            query.setParameter(i + "" , params[i]);
        }
        return (List<T>)query.list();
    }
    /**
     * 使用hql 语句进行分页查询操作
     * @param hql 需要查询的hql语句
     * @param pageNo 查询第pageNo页的记录
     * @param pageSize 每页需要显示的记录数
     * @return 当前页的所有记录
     */
    @SuppressWarnings("unchecked")
    protected List<T> findByPage(String hql,
                                 int pageNo, int pageSize)
    {
        // 创建查询
        return sessionFactory.getCurrentSession()
                .createQuery(hql)
                        // 执行分页
                .setFirstResult((pageNo - 1) * pageSize)
                .setMaxResults(pageSize)
                .list();
    }
    /**
     * 使用hql 语句进行分页查询操作
     * @param hql 需要查询的hql语句
     * @param params 如果hql带占位符参数，params用于传入占位符参数
     * @param pageNo 查询第pageNo页的记录
     * @param pageSize 每页需要显示的记录数
     * @return 当前页的所有记录
     */
    @SuppressWarnings("unchecked")
    protected List<T> findByPage(String hql , int pageNo, int pageSize
            , Object... params)
    {
        // 创建查询
        Query query = sessionFactory.getCurrentSession()
                .createQuery(hql);
        // 为包含占位符的HQL语句设置参数
        for(int i = 0 , len = params.length ; i < len ; i++)
        {
            query.setParameter(i + "" , params[i]);
        }
        // 执行分页，并返回查询结果
        return query.setFirstResult((pageNo - 1) * pageSize)
                .setMaxResults(pageSize)
                .list();
    }
}
